/**
 * 
 */
package com.tianxiao.test.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.tianxiao.test.dao.ConflictCheckDao;
import com.tianxiao.test.model.ConflictCheck;
import com.tianxiao.test.result.ConflictResult;
import com.tianxiao.test.service.ConflictCheckService;

/**
 * @author leiruiqi
 *
 */

@Service("conflictCheckService")
public class ConflictCheckServiceImpl implements ConflictCheckService {

	@Resource
	ConflictCheckDao conflictCheckDao;
	
	
	@Override
	public ConflictResult<List<ConflictCheck>> check(ConflictCheck conflictCheck) {
		ConflictResult<List<ConflictCheck>> result = new ConflictResult<List<ConflictCheck>>();
		List<ConflictCheck>  list = conflictCheckDao.queryConflictByCondition(conflictCheck);
		
		if(list.size() == 1&& conflictCheck.getId()!=null){
			if(list.get(0).getId().equals(conflictCheck.getId()) ){
				result.setSuccese(true);
			}
		}
		
		int size = list.size();
		
		if(size == 0){
			result.setSuccese(true);
		}else{
			result.setSuccese(false);
			result.setResult(list);
		}
		
		return result;
	}

	
	@Override
	@Transactional( propagation = Propagation.REQUIRED )
	public ConflictResult<List<ConflictCheck>> save(ConflictCheck conflictCheck) {
		//上锁并等待
		boolean locked = lockAndWaitForSave();
		if(!locked){
			return new ConflictResult<List<ConflictCheck>>();
		}
		//冲突检测
		ConflictResult<List<ConflictCheck>> checkResult = check(conflictCheck);
		//冲突则直接返回
		if(!checkResult.isSuccese()){
			return checkResult;
		}
		//无冲突执行入库操作
		Integer count;
		if(conflictCheck.getId()!=null){
			count = conflictCheckDao.update(conflictCheck);
			
		}else{
			conflictCheckDao.save(conflictCheck);;
			count=1;
		}
		
		unlockForSave();
		
		if(count == 1){
			checkResult.setSuccese(true);
		}else{
			checkResult.setSuccese(false);
		}
		return checkResult;
	}

	
	private boolean lockAndWaitForSave(){
		//方法很多
		//1、普通配置表建一条特性的记录，每次操作去锁这条记录，使用sql的select forupdate ，如果被锁住会一直等待。直到上个线程释放这条记录。
		//2、使用MemoCache或者Redis对一个key上锁，memecache完美支持，redis由于api受限，操作的麻烦一点，
		//3、其他锁，zookeeper等等
		String key = "conflict_check_lock";
		/*SysConfig sysConfig = sysConfigService.selectOneForLock(key);
		if(sysConfig == null){
			return false;
		}else{
			return true;
		}*/
		return true;
	}
	
	private void unlockForSave(){
		
	}
	
	@Override
	public ConflictResult<List<ConflictCheck>> queryByConditonRange(ConflictCheck conflictCheck) {
		ConflictResult<List<ConflictCheck>> queryResult = new ConflictResult<List<ConflictCheck>>();
		List<ConflictCheck> list = this.conflictCheckDao.queryByConditonRange(conflictCheck);
		queryResult.setSuccese(true);
		queryResult.setResult(list);
		return queryResult;
	}
	
	@Override
	public ConflictResult<Map<String,List<ConflictCheck>>> queryForGroupByConditonRange(ConflictCheck conflictCheck) {
		ConflictResult<Map<String,List<ConflictCheck>>> queryResult = new ConflictResult<Map<String,List<ConflictCheck>>>();
		queryResult.setSuccese(true);
		Map<String,List<ConflictCheck>> map = new HashMap<String,List<ConflictCheck>>();
		List<ConflictCheck> list = this.conflictCheckDao.queryByConditonRange(conflictCheck);
		if(list.size()>0){
			Long courseId = conflictCheck.getCourseId();
			Long classroomId = conflictCheck.getClassroomId();
			Long teacherId = conflictCheck.getTeacherId();
			
			for(ConflictCheck conflict:list){
				
				if(courseId!=null){
					List<ConflictCheck> listConflict = map.get("course");
					if(listConflict == null){
						listConflict = new ArrayList<ConflictCheck>();
						map.put("course", listConflict);
					}
					if(conflict.getCourseId()!=null && conflict.getCourseId().equals(courseId)){
						listConflict.add(conflict);
					}
				}
				if(classroomId!=null){
					List<ConflictCheck> listConflict = map.get("classroom");
					if(listConflict == null){
						listConflict = new ArrayList<ConflictCheck>();
						map.put("classroom", listConflict);
					}
					if(conflict.getClassroomId()!=null && conflict.getClassroomId().equals(classroomId)){
						listConflict.add(conflict);
					}
				}
				if(teacherId!=null){
					List<ConflictCheck> listConflict = map.get("teacher");
					if(listConflict == null){
						listConflict = new ArrayList<ConflictCheck>();
						map.put("teacher", listConflict);
					}
					if(conflict.getTeacherId()!=null && conflict.getTeacherId().equals(teacherId)){
						listConflict.add(conflict);
					}
				}
			}
		}
		queryResult.setResult(map);
		return queryResult;
	}

}
